/*
 * db_mysql.cpp
 *
 *  Created on: 2016年12月6日
 *      Author: work
 */

#include <os/db/db_mysql.hpp>
#include <cppconn/exception.h>
#include <cppconn/statement.h>
#include <cppconn/sqlstring.h>

namespace iotplat {

    CDbMysql::CDbMysql(const char *dbName, const char *host) : CDb(dbName, host) {
        m_driver = NULL;
        m_con = NULL;
    }

    CDbMysql::~CDbMysql() {
        if (m_con != NULL)
            delete m_con;
    }

    CDb::EDbType CDbMysql::dbType() {
        return DtMysql;
    }

    bool CDbMysql::isConnected() {
        if (m_con != NULL)
            return m_con->isValid();
        return false;
    }

    bool CDbMysql::connect(const char *user, const char *pw) {
        try {
            if (m_driver == NULL)
                m_driver = get_driver_instance();
            if (m_driver == NULL) {
                std::cout << __FUNCTION__ << "获取数据库驱动失败" << std::endl;
                return false;
            }

            if (m_con == NULL) {
                m_con = m_driver->connect(m_host.c_str(), user, pw);
                if (m_con == NULL) {
                    std::cout << __FUNCTION__ << "连接数据库失败" << user << "  " << m_host << std::endl;
                    return false;
                }


                m_con->setSchema(m_dbName.c_str());
                return true;
            } else {
                m_con->setSchema(m_dbName.c_str());

                return m_con->reconnect();
            }
        }
        catch (sql::SQLException &e) {
            std::cout << __FUNCTION__ << e.what() << std::endl;
            return false;
        }

        return false;
    }

    void CDbMysql::disconnect() {
        try {
            if (m_con)
                m_con->close();
        }
        catch (sql::SQLException &e) {
            std::cout << __FUNCTION__ << e.what() << std::endl;
        }

        if (m_con) {
            delete m_con;
            m_con = NULL;
        }
    }

    bool CDbMysql::exec(const char *sql) {
        sql::Statement *stmt = NULL;
        if (isConnected()) {
            try {
                stmt = m_con->createStatement();
                if (stmt == NULL) {
                    std::cout << __FUNCTION__ << "准备语句失败" << std::endl;
                } else {
                    stmt->execute(sql);
                    delete stmt;
                    return true;
                }
            } catch (sql::SQLException &e) {
                if (e.getErrorCode() == 1043 || e.getErrorCode() == 2006)
                    disconnect();
            }
        } else {
            //log().warnning(logModule,this,__FUNCTION__,"没有连接");
        }

        if (stmt)
            delete stmt;

        return false;
    }

    CResultSet *CDbMysql::query(const char *sql) {
        if (isConnected()) {
            try {
                sql::Statement *stmt = m_con->createStatement();
                if (stmt == NULL) {
                    //log().error(logModule,this,__FUNCTION__,"准备语句失败");
                } else {
                    sql::ResultSet *rt = stmt->executeQuery(sql);
                    if (rt != NULL) {
                        CResultSetMysql *rs = new CResultSetMysql();
                        rs->set(rt, stmt);
                        return rs;
                    } else {
                        //log().error(logModule,this,__FUNCTION__,"执行语句失败%s",sql);
                        delete stmt;
                    }
                }
            } catch (sql::SQLException &e) {
                //log().error(logModule,this,__FUNCTION__,e.what());
                return NULL;
            }
        }

        return NULL;
    }

/**
 * 获取匹配字符串表名
 * @param pattern
 * @param rs
 * @return
 */
    CResultSet *CDbMysql::getTables(const char *pattern) {
        std::string sql = "select table_name from information_schema.tables where table_type='BASE TABLE' and table_name like '";
        sql += pattern;
        sql += "'";

        return query(sql.c_str());
    }

    int64_t CDbMysql::execWithLastId(const char *sql) {
        return 0;
    }

}